///////////////////////////////////////////////////////////////////////
// File:        Sink.cpp
// Description: 
// Author:      Philip Kommnick
// Created:     Fri September 11 12:14:29 CEST 2009
//
// This program is open source. For license terms, see the LICENSE file.
//
///////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "Sink.h"
#include "resource.h"

unsigned int Sink::outCount = 0;

Sink::Sink() : /*fileDlg*/saveDlg(NULL)
{
	if (FAILED(CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&saveDlg))))
		throw std::exception("blubb");
	saveDlg->SetOptions(FOS_DEFAULTNOMINIMODE | FOS_STRICTFILETYPES | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_NOREADONLYRETURN | FOS_DONTADDTORECENT);
}

Sink::~Sink(void)
{
	saveDlg->Release();
}

void Sink::InitFileDlg(TypesList &fileTypes)
{
	if (fileTypes.empty())
		throw std::exception("empty type list");
	fileExtList.clear();
	COMDLG_FILTERSPEC *typeArray = new COMDLG_FILTERSPEC[fileTypes.size()];
	for (size_t i=0; i<fileTypes.size(); i++) {
		typeArray[i].pszName=fileTypes[i].first.c_str();
		typeArray[i].pszSpec=fileTypes[i].second.c_str();
		fileExtList.push_back(fileTypes[i].second);
	}
	if (FAILED(saveDlg->SetFileTypes(fileTypes.size(), typeArray)))
		throw std::exception("could not set filter list");
	saveDlg->SetFileTypeIndex(fileTypes.size() ? 1 : 0);
	delete[] typeArray;
	CreateFileExt();
}

UINT Sink::CreateFileExt(void)
{
	UINT filterIdx;
	saveDlg->GetFileTypeIndex(&filterIdx);
	size_t stIdx = fileExtList[filterIdx-1].find(L"*.")+2;
	size_t endIdx = fileExtList[filterIdx-1].find(L';', stIdx);
	if (endIdx==std::wstring::npos)
		endIdx = fileExtList[filterIdx-1].length()-1;
	fileExt = fileExtList[filterIdx-1].substr(stIdx, endIdx);
	return filterIdx;
}

bool Sink::RequestFileName(std::wstring title)
{
	saveDlg->SetTitle(title.c_str());
	std::wstringstream nextFileName;
	nextFileName << L"scan";
	nextFileName.width(4);
	nextFileName.fill(L'0');
	nextFileName << ++outCount;
	//nextFileName.width(0);
	//nextFileName << L'.' << fileExt;
	saveDlg->SetFileName(nextFileName.str().c_str());
	int response;
	bool allOk = false;
	do {
		response = IDYES;

		if (FAILED(saveDlg->Show(MainWin::hWnd)))
			return false;

		IShellItem *item = NULL;
		if (SUCCEEDED(saveDlg->GetResult(&item))) {
			fileExt.clear();
			wchar_t *path = NULL, *fileOffset = NULL, *extOffset = NULL;
			if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &path))) {
				allOk = true;
				fileName = path;
				fileOffset = wcsrchr(path, L'\\');
				if (fileOffset)
					extOffset = wcsrchr(fileOffset+1, L'.');
				if (extOffset) {
					UINT filterIdx;
					saveDlg->GetFileTypeIndex(&filterIdx);
					size_t findIdx, findEndIdx;
					findIdx = fileExtList[filterIdx-1].find(extOffset);
					findEndIdx = fileExtList[filterIdx-1].find(L';');
					if (findEndIdx==std::wstring::npos)
						findEndIdx=fileExtList[filterIdx-1].length();
					if (findIdx!=std::wstring::npos && !fileExtList[filterIdx-1].substr(findIdx, findEndIdx-1).compare(extOffset))
						fileExt = extOffset+1;
				}
				CoTaskMemFree(path);
				if (fileExt.empty()) {
					CreateFileExt();
					fileName += L"." + fileExt;
				}
				WIN32_FIND_DATA fileInfo;
				HANDLE testExist = FindFirstFile(fileName.c_str(), &fileInfo);
				if (testExist!=INVALID_HANDLE_VALUE) {
					FindClose(testExist);
					std::wstring shortFile = fileName.substr(fileName.rfind(L'\\')+1);
					shortFile += L" already exists.";
					TaskDialog(MainWin::hWnd, tpInstance, MAKEINTRESOURCE(IDS_APPNAME), shortFile.c_str(), MAKEINTRESOURCE(IDS_FILEREPLACE), TDCBF_YES_BUTTON | TDCBF_NO_BUTTON, TD_WARNING_ICON, &response);
				}
			}
			item->Release();
		}
	} while(response==IDNO);
	return allOk;
}